(function($) {
	$.fn.autoFile = function (options) {
		var ratio = window.devicePixelRatio || 1;// 优化retina, 在retina下这个值是2
		var setting = {
			auto:false,
			fileVal : "_file",
			fileNumLimit : 10,
			fileSizeLimit : 200 * 1024 * 1024,    // 200 M
            fileSingleSizeLimit : 50 * 1024 * 1024 ,   // 50 M
            totalFileNum : 0 ,
            totalFileSize : 0,
			paste : null,
			dnd : null,
			disableGlobalDnd : true,
			accept : {
                title: 'allTypes',
                extensions: 'txt,pdf,ppt,pptx,doc,docx,xls,xlsx,zip,rar,gz,7z,gif,jpg,jpeg,bmp,png,html,htm'
            },
			formData : {},
			totalPercentage  :{},
			thumbnailWidth : 110 * ratio,
			thumbnailHeight : 110 * ratio,
            state : 'pedding',// 可能有pedding, ready, uploading, confirm, done.
			swf :  '../webuploader/Uploader.swf',
			server : "atta/upload/",
			files_url : "atta/files/",
			title : "文件",
			targetId : null,
			dataId : null,
			callback : null,
			readonly : false
		};
		setting = $.extend(setting, options);
		var $this=$(this);
		var readonly = isReadonly($this);
		setting.readonly = readonly;
		setting.callback = getFunction(this.data("callback"));
		$this.hide();
		var id=$this.attr("id");
		var dataId = $this.data("data-id");
		setting.targetId=id;
		setting.dataId=dataId;
		setting.fileNumLimit=trim($this.data("file-num-limit"),"10");
		setting.title=trim($this.data("title"),"文件");
		var singleFile = setting.fileNumLimit < 2;
		
		var warpId="uploader_"+id;
		setting.paste="#"+warpId;
		var warp="<div id='"+warpId+"' class='uploader' title='"+setting.title+"'><input type='hidden' id='"+id+"_del' name='"+id+"_del'>";
		if(readonly){
			warp+="<div class='queueList'><ul class='filelist "+(singleFile ? "singlefile" : "")+"'></ul></div>";
		}else{
			var dndId="dnd_area_"+id;
			warp+="<div class='queueList'><div id='"+dndId+"' class='placeholder'><div class='filePicker'></div> <p></p></div><ul class='filelist element-invisible "+(singleFile ? "singlefile" : "")+"'></ul></div>";
			if(!singleFile){
				warp+="<div class='statusBar element-invisible '><div class='progressbar'><span class='text'>0%</span><span class='percentage'></span> </div>";
				warp+="<div class='info'></div>";
				warp+="<div class='btns'> <div class='filePickerMore'></div><div class='uploadBtn'>开始上传</div> </div>";
				warp+="</div>";
			}
		}
		warp+="</div>";
		warp=$(warp);
		$this.after(warp);
		if(!readonly){
			setting.dnd="#"+dndId;
			setting.fileVal=id+"_file";
			setting.server+=id;
			if($this.data("image")){
				setting.accept={
					title: 'Images',
				    extensions: 'gif,jpg,jpeg,bmp,png',
				    mimeTypes: 'image/*'			
				};
			};			
			setting.pick={
                id: warp.find(".filePicker"),
                innerHTML : "点击选择"+setting.title
	        };
			if(singleFile){
				setting.auto=true;
			}
			var uploader = WebUploader.create(setting);
			warp.data("uploader",uploader);
			
			// 添加“添加文件”的按钮，
			if(!singleFile){
		        uploader.addButton({
		            id: warp.find(".filePickerMore"),
		            innerHTML: '继续添加'
		        });
			}
	        // 拖拽时不接受 js, txt 文件。
	        uploader.on( 'dndAccept', function( items ) {
	            var denied = false, len = items.length, i = 0, unAllowed = 'text/plain;application/javascript ';// 修改js类型
	            for ( ; i < len; i++ ) {
	                if ( ~unAllowed.indexOf( items[ i ].type ) ) {// 如果在列表里面
	                    denied = true;
	                    break;
	                }
	            }
	            return !denied;
	        });
	        //进度条
	        uploader.onUploadProgress = function( file, percentage ) {
	            var $li = $('#'+file.id);
	            var $percent = $li.find('.progressbar span');

	            $percent.css( 'width', percentage * 100 + '%' );
	            this.options.totalPercentage[ file.id ][ 1 ] = percentage;
	            updateTotalProgress(this);
	        };
	        //当文件被加入队列之前触发。如果此事件handler的返回值为false，则此文件不会被添加进入队列。
	        uploader.on('beforeFileQueued',function( file ) {
	            if(this.options.fileNumLimit>this.options.totalFileNum){
	            	return true;
	            }else{
	            	showMsg( 'Error: 总共只能上传'+this.options.fileNumLimit+'个文件'  ,"error");
	            	return false;
	            }
	        });
	        //新增文件队列
	        uploader.onFileQueued = function( file ) {
	            addUploaderFile( file ,this);
	        };
	        //删除文件队列
	        uploader.onFileDequeued = function( file ) {
	        	//removeUploaderFile( file ,this);
	        };
	        //当文件上传成功时触发
	        uploader.on('uploadSuccess', function(file,data) {
	        	var $li=$("#"+ file.id);
	        	if(data.success){
	        		var af=data.data;
	        		this.getFile(file.id)["fileid"]=af.id;
	        		$li.data("fileid",af.id);
	        		$li.append('<span class="success"></span>');
	        		$li.find("p.error").remove();
	        		$li.find( 'p.imgWrap' ).wrapInner("<a target='_blank' href='"+af.uri+"'></a>");
	        	}else{
	        		showUploaderError($li, trim(data.msg,"文件上传失败"));
	        	}
	        });
	        //webuploader加载完成
	        uploader.on('ready', function() {
	        	loadAutoFile(this);
	        	if(null!= this.options.callback){
	        		this.options.callback.call(this);
	        	}
	        });
	        //当所有文件上传结束时触发
	        uploader.on('uploadFinished', function() {
	        	setUploaderState( 'confirm' ,this);
                setTargetFile(this);
	        });
	        //文件开始上传时触发
	        uploader.on('startUpload', function() {
	        	setUploaderState( 'uploading' ,this);
	        });
	        //文件上传中止时触发
	        uploader.on('stopUpload', function() {
	        	setUploaderState( 'paused' ,this);
                setTargetFile(this);
	        });
	        //异常提醒
	        uploader.onError = function( code , file) {
	        	var msg="系统异常";
	            switch (code){
		        	case 'F_DUPLICATE':
			            msg = '文件已存在';
			            break;
			        case 'Q_EXCEED_NUM_LIMIT':
			            msg = '总共只能上传'+this.options.fileNumLimit+'个文件';
			            break;
			        case 'Q_EXCEED_SIZE_LIMIT':
			            msg = '总计只能上传'+WebUploader.formatSize( this.options.fileSizeLimit )+'文件，且单个文件不能超过'+WebUploader.formatSize( this.options.fileSingleSizeLimit );
			            break;
			        case 'Q_TYPE_DENIED':
			            msg = '只能上传后缀名为'+this.options.accept[0].extensions+'的文件';
			            break;
	            };
	            showMsg( 'Error: ' + msg ,"error");
	        };
	        
	        var $uploadBtn=$(setting.paste + " div.uploadBtn");
	        $uploadBtn.on('click', function() {//上传按钮
	            if ( $(this).hasClass( 'disabled' ) ) {
	                return false;
	            }
	            var state=uploader.options.state;
	            if ( state === 'ready' ) {
	                uploader.upload();
	            } else if ( state === 'paused' ) {
	                uploader.upload();
	            } else if ( state === 'uploading' ) {
	                uploader.stop();
	            }
	        });
	        $uploadBtn.addClass( 'state-' + uploader.options.state );
	        //$uploadBtn.attr("title",setting.title+"允许文件类型:"+setting.accept.extensions);
	        var $info=$(setting.paste + " div.info");
	        $info.on( 'click', '.retry', function() {//重新上传
	            uploader.retry();
	        } );
	        $info.on( 'click', '.ignore', function() {//忽略文件
	        	$("#uploader_" + uploader.options.targetId + " ul.filelist > li.state-error").each(function(){
	        		var $li=$(this);
	        		removeUploaderFile(uploader.getFile( $li.attr("id")) ,uploader);
	        	});
	        } );
	        updateTotalProgress(uploader);
		}else{
			loadAutoFile({options:setting});
			$(setting.paste + " ul.filelist").show();
		}
	};
	
})(window.jQuery);

function getFileHtml(file){
	var html=null;
	if (isImage(file.name) && !_.isUndefined(file.src)) {
		html="<img src='"+file.src+"'>";
	}else{
		var ext = getFileExt(file.name);
		var css="fa-file-text-o";
		if ("doc" == ext || "docx" == ext) {
			css = "fa-file-word-o";
		} else if ("xls" == ext || "xlsx" == ext) {
			css = "fa-file-excel-o";
		} else if ("ppt" == ext || "pptx" == ext) {
			css = "fa-file-powerpoint-o";
		} else if ("pdf" == ext) {
			css = "fa-file-pdf-o";
		} else if ("mp3" == ext || "wav" == ext) {
			css = "fa-file-sound-o";
		} else if ("mp4" == ext || "rm" == ext || "rmvb" == ext || "avi" == ext) {
			css = "fa-file-video-o";
		} else if ("zip" == ext || "rar" == ext || "gz" == ext || "7z" == ext) {
			css = "fa-file-archive-o";
		} else if ("jpg" == ext || "jpeg" == ext || "gif" == ext || "bmp" == ext || "png" == ext) {
			css = "fa-file-archive-o";
		}
		html="<i class='fa "+css+"'>&nbsp;&nbsp;"+file.name+"</i>";
	}
	if(file.getStatus() === 'complete' && !_.isUndefined(file.src)){//历史文件，添加下载链接
		html="<a href='"+file.src+"' target='_blank'>"+html+"</a>";
	}
	return $(html);
}
// 当有文件添加进来时执行，负责view的创建
function addUploaderFile(file, uploader) {
	var readonly = uploader.options.readonly;
	var contianerId = uploader.options.paste;
	var $filelist = $(contianerId + " ul.filelist");
	var $li = $('<li id="' + file.id + '" title="' + file.name + '">' + '<p class="imgWrap"></p>' + '</li>');
	var $wrap = $li.find('p.imgWrap');
	var $btns = null, $prgress = null;
	if (readonly) {// 只有历史文件才有可能只读
		$wrap.append(getFileHtml(file));
	} else {
		$btns = $( '<div class="file-panel"><span class="cancel">删除</span></div>') .appendTo($li);
		$prgress = $('<p class="progressbar"><span></span></p>').appendTo($li);
		$prgress = $prgress.find('span');
		if (file.getStatus() === 'invalid') {// 错误
			showUploaderError($li, file.statusText);
		} else {
			if (file.getStatus() === 'complete') {// 历史文件
				var temp = getFileHtml(file);
				$wrap.append(temp);
				$li.data("fileid",file.fileid).addClass("state-complete").append('<span class="success"></span>');
				uploader.options.totalPercentage[file.id] = [ file.size, 1 ];// 进度为100%
			} else {
				uploader.makeThumb(file, function(error, src) {
					if (error || !isSupportBase64) {
						$wrap.append(getFileHtml(file));
						return;
					}
					if (isSupportBase64) {
						file.src=src;
						$wrap.append(getFileHtml(file));
					}
				}, uploader.options.thumbnailWidth,
						uploader.options.thumbnailHeight);
				file.on('statuschange', function(cur, prev) {
					if (prev === 'progress') {
						$prgress.hide();
					} else if (prev === 'queued') {
						// $li.off( 'mouseenter mouseleave' );
					}

					if (cur === 'error' || cur === 'invalid') {
						// console.log( file.statusText );
						showUploaderError($li, file.statusText);
						uploader.options.totalPercentage[file.id][1] = 1;
					} else if (cur === 'interrupt') {
						showUploaderError($li, 'interrupt');
					} else if (cur === 'queued') {
						//$(uploader.options.paste + " div.info").remove();
						$prgress.css('display', 'block');
						uploader.options.totalPercentage[file.id][1] = 0;
					} else if (cur === 'progress') {
						//$(uploader.options.paste + " div.info").remove();
						$prgress.css('display', 'block');
					} else if (cur === 'complete') {
						$prgress.hide();
					}
					$li.removeClass('state-' + prev).addClass('state-' + cur);
				});
				uploader.options.totalPercentage[file.id] = [ file.size, 0 ];
				file.rotation = 0;
			}
			$li.on('mouseenter', function() {
				$btns.stop().animate({
					height : 30
				});
			});

			$li.on('mouseleave', function() {
				$btns.stop().animate({
					height : 0
				});
			});

			$btns.on('click', 'span', function() {
				var index = $(this).index(), deg;
				switch (index) {
				case 0:// 删除队列
					removeUploaderFile(file, uploader);
					return;
				case 1:// 右旋转
					file.rotation += 90;
					break;
				case 2:// 左旋转
					file.rotation -= 90;
					break;
				}

				if (isSupportTransition) {
					deg = 'rotate(' + file.rotation + 'deg)';
					$wrap.css({ '-webkit-transform' : deg, '-mos-transform' : deg, '-o-transform' : deg, 'transform' : deg });
				} else {
					$wrap.css('filter', 'progid:DXImageTransform.Microsoft.BasicImage(rotation=' + (~~((file.rotation / 90) % 4 + 4) % 4) + ')');
				}
			});
		}
		
		uploader.options.totalFileNum ++;
		uploader.options.totalFileSize += file.size;

		if (uploader.options.totalFileNum === 1) {
			$(contianerId + " div.placeholder").addClass('element-invisible');
			//$(contianerId + " div.statusBar").show();
			$(contianerId + " ul.filelist").removeClass('element-invisible');
		}
		setUploaderState('ready', uploader);
		updateTotalProgress(uploader);
	}
	$filelist.append($li);
};

// 删除文件队列
function removeUploaderFile( file ,uploader) {
    var $li = $('#'+file.id);
    delete uploader.options.totalPercentage[ file.id ];
    uploader.options.totalFileNum --;
	uploader.options.totalFileSize -= file.size;
	if(uploader.getFile(file.id)){//如果存在对列中的文件
		uploader.removeFile( file , true );
	}
    if(_.isNumber(file.fileid)){//已上传文件
    	setTargetFile(uploader,file.fileid);
    }
    $li.off().find('.file-panel').off().end().remove();
    if ( uploader.options.totalFileNum < 1) {
        setUploaderState( 'pedding',uploader );
    }else{
    	updateUploaderStatus(uploader);
    }
    updateTotalProgress(uploader);
};

function updateTotalProgress(uploader) {
    var loaded = 0,
        total = 0,  percent = 0;
    var spans = $(uploader.options.paste+" div.progressbar").children();

    $.each( uploader.options.totalPercentage, function( k, v ) {
        total += v[ 0 ];
        loaded += v[ 0 ] * v[ 1 ];
    } );
    percent = total ? loaded / total : 0;
    spans.eq( 0 ).text( Math.round( percent * 100 ) + '%' );
    spans.eq( 1 ).css( 'width', Math.round( percent * 100 ) + '%' );
    updateUploaderStatus(uploader);
};

function updateUploaderStatus(uploader) {
    var text = '', stats;
    var state = uploader.options.state;
    if ( state === 'ready' ) {
        text = '总数量: ' + uploader.options.totalFileNum + '（' +  WebUploader.formatSize( uploader.options.totalFileSize ) + '）';
    } else if ( state === 'confirm' ) {
        stats = uploader.getStats();
        if ( stats.uploadFailNum ) {
            text = '成功上传数量: ' + stats.successNum+ '，上传失败数量: '+
                stats.uploadFailNum + '，<a class="retry" href="#">重新上传</a>或<a class="ignore" href="#">忽略</a>'
        }
    } else {
        stats = uploader.getStats();
        text = '总数量: ' + uploader.options.totalFileNum + '（' +  WebUploader.formatSize( uploader.options.totalFileSize )  +  '），已上传数量: ' + stats.successNum ;

        if ( stats.uploadFailNum ) {
            text += '，失败数量: ' + stats.uploadFailNum;
        }
    }

    $(uploader.options.paste+" div.info").html( text );
};

function setUploaderState( val,uploader ) {
    var file = null;
    var stats = uploader.getStats();
    var state = uploader.options.state;
    
    if ( val === state ) {
        return;
    }
    state = val;
	var warpId = uploader.options.paste;
	var $uploadBtn = $(warpId + " div.uploadBtn");
	$uploadBtn.removeClass('state-' + state);
	$uploadBtn.addClass('state-' + val);
	var $placeholder = $(warpId + " div.placeholder");
	var $filelist = $(warpId + " ul.filelist");
	var $statusBar = $(warpId + " div.statusBar");
	var $filePickerMore = $(warpId + " div.filePickerMore");
	var $progress = $(warpId + " div.progressbar");
    switch ( state ) {
        case 'pedding':
        	$placeholder.removeClass( 'element-invisible' );
        	$filelist.hide();
        	$statusBar.addClass( 'element-invisible' );
            uploader.refresh();
            break;

        case 'ready':
        	$placeholder.addClass( 'element-invisible' );
        	$filePickerMore.removeClass( 'element-invisible');
            $filelist.show();
            $statusBar.removeClass('element-invisible');
            uploader.refresh();
            break;

        case 'uploading':
        	$filePickerMore.addClass( 'element-invisible' );
        	//$progress.show();
        	$uploadBtn.text( '暂停上传' );
            break;

        case 'paused':
        	//$progress.show();
        	$uploadBtn.text( '继续上传' );
            break;

        case 'confirm':
        	//$progress.hide();
        	$filePickerMore.removeClass( 'element-invisible' );
        	$uploadBtn.text( '开始上传' );
            if ( stats.successNum && !stats.uploadFailNum ) {
                setUploaderState( 'finish',uploader );
                return;
            }
            break;
        case 'finish':
        	state = 'done';
            break;
    }
    uploader.options.state=state;
    updateUploaderStatus(uploader);
};

function showUploaderError ($li , code ) {
	var text = code;
	var $info = $li.find("div.info");
	if($info.length<1){
		$info=$('<p class="error"></p>');
		$info.appendTo( $li );
	}
    switch( code ) {
        case 'exceed_size':
            text = '文件大小超出';
            break;
        case 'interrupt':
            text = '上传暂停';
            break;
        case 'server':
            text = '服务器异常';
            break;
        case 'abort':
            text = '网络错误';
            break;                    
    }
    $info.text( text );
};
function setTargetFile(uploader,delFileId){
	var adds = "";
	$("#uploader_" + uploader.options.targetId + " ul.filelist > li").each(
			function() {
				var fileId = $(this).data("fileid");
				if (!_.isNumber(fileId)) {
					return;// 未上传
				}
				if (adds != "") {
					adds += ","
				}
				adds += fileId;
			});
	$("#" + uploader.options.targetId).val(adds);
	// 删除的文件
	if (_.isNumber(delFileId)) {
		var delIpt = $("#" + uploader.options.targetId + "_del");
		var delIds = delIpt.val();
		if (delIds != "") {
			delIds += ","
		}
		delIds += delFileId;
		delIpt.val(delIds);
	}
};
function loadAutoFile(uploader){
	if(_.isEmpty(uploader.options.targetId)||!_.isNumber(uploader.options.dataId))return;
	var uri=trim(uploader.options.files_url,"atta/files/");
	uri+=(uploader.options.targetId+"-"+uploader.options.dataId);
	$.get(uri,function(data){
		if( data.success ){
			data = data.data;
			for(var i=0;i<data.length;i++){
				var af = data[i];
				var file = {};
				file.name = af.name;
				file.id = "AF_" + af.id;
				file.fileid = af.id;
				file.size = af.size;
				file.type = af.mimeType;
				file.ext = af.ext
				file.src = af.uri;
				file.source = this;
				file.flog = true;
				file.version = WebUploader.Base.version;
				file.status = "complete";
				file.getStatus = function(){  
                    return this.status;  
                };
				file.statusText = '历史文件';  
				file.setStatus = function(st){  
					this.status=st;
                };
                addUploaderFile( file , uploader );
			}
		}else{
			showMsg(data.msg,"error");
		}
	});
};

//如果文件上传的页面初始化时是隐藏的，文件选择按钮由于大小设置为1px，click事件无法响应，需要重新刷新上传实例
function refreshUploader(warp){
	warp.find("div.uploader").each(function(){
		var temp=$(this).data("uploader");
		if(_.isUndefined(temp)||!_.isFunction(temp.refresh)){
			return;
		}
		if(!temp.isAutoRefresh){//是否刷新过
			setTimeout(function(){
				temp.refresh();
				temp.isAutoRefresh=true;
			}, 300);
		}
	});
}